{
 "metadata": {
  "name": "",
  "signature": "sha256:42ec5f60b4b162e35116ce250065b4b76318fa8b9a60bbea5ff2bf2d70637484"
 },
 "nbformat": 3,
 "nbformat_minor": 0,
 "worksheets": [
  {
   "cells": [
    {
     "cell_type": "markdown",
     "metadata": {},
     "source": [
      "# Decision Trees\n",
      "\n",
      "*Adapted from Chapter 8 of [An Introduction to Statistical Learning](http://www-bcf.usc.edu/~gareth/ISL/)*"
     ]
    },
    {
     "cell_type": "markdown",
     "metadata": {},
     "source": [
      "**Motivation:** Why are we learning about decision trees?\n",
      "\n",
      "- Useful for both regression and classification problems\n",
      "- Widely used\n",
      "- Basis for more sophisticated models\n",
      "- Have a different way of \"thinking\" than the other models we have studied"
     ]
    },
    {
     "cell_type": "markdown",
     "metadata": {},
     "source": [
      "# Part 1: Regression trees\n",
      "\n",
      "Baseball player salary data:\n",
      "\n",
      "- **Years** (x-axis): number of years playing in the major leagues\n",
      "- **Hits** (y-axis): number of hits in the previous year\n",
      "- **Salary** (color): low salary is blue/green, high salary is red/yellow"
     ]
    },
    {
     "cell_type": "markdown",
     "metadata": {},
     "source": [
      "![Salary data](images/salary_color.png)"
     ]
    },
    {
     "cell_type": "markdown",
     "metadata": {},
     "source": [
      "Group exercise:\n",
      "\n",
      "- The data above is our **training data**.\n",
      "- We want to build a model that predicts the Salary of **future players** based on Years and Hits.\n",
      "- We are going to \"segment\" the feature space into regions, and then use the **mean Salary in each region** as the predicted Salary for future players.\n",
      "- Intuitively, you want to **maximize** the similarity (or \"homogeneity\") within a given region, and **minimize** the similarity between different regions.\n",
      "\n",
      "Rules for segmenting:\n",
      "\n",
      "- You can only use **straight lines**, drawn one at a time.\n",
      "- Your line must either be **vertical or horizontal**.\n",
      "- Your line **stops** when it hits an existing line."
     ]
    },
    {
     "cell_type": "markdown",
     "metadata": {},
     "source": [
      "![Salary regions](images/salary_regions.png)"
     ]
    },
    {
     "cell_type": "markdown",
     "metadata": {},
     "source": [
      "Above are the regions created by a computer:\n",
      "\n",
      "- $R_1$: players with **less than 5 years** of experience, mean Salary of **\\$166,000 **\n",
      "- $R_2$: players with **5 or more years** of experience and **less than 118 hits**, mean Salary of **\\$403,000 **\n",
      "- $R_3$: players with **5 or more years** of experience and **118 hits or more**, mean Salary of **\\$846,000 **\n",
      "\n",
      "**Note:** Years and Hits are both integers, but the convention is to use the **midpoint** between adjacent values to label a split.\n",
      "\n",
      "These regions are used to make predictions on **out-of-sample data**. Thus, there are only three possible predictions! (Is this different from how **linear regression** makes predictions?)\n",
      "\n",
      "Below is the equivalent regression tree:"
     ]
    },
    {
     "cell_type": "markdown",
     "metadata": {},
     "source": [
      "![Salary tree](images/salary_tree.png)"
     ]
    },
    {
     "cell_type": "markdown",
     "metadata": {},
     "source": [
      "The first split is **Years < 4.5**, thus that split goes at the top of the tree. When a splitting rule is **True**, you follow the left branch. When a splitting rule is **False**, you follow the right branch.\n",
      "\n",
      "For players in the **left branch**, the mean Salary is \\$166,000, thus you label it with that value. (Salary has been divided by 1000 and log-transformed to 5.11.)\n",
      "\n",
      "For players in the **right branch**, there is a further split on **Hits < 117.5**, dividing players into two more Salary regions: \\$403,000 (transformed to 6.00), and \\$846,000 (transformed to 6.74)."
     ]
    },
    {
     "cell_type": "markdown",
     "metadata": {},
     "source": [
      "![Salary tree annotated](images/salary_tree_annotated.png)"
     ]
    },
    {
     "cell_type": "markdown",
     "metadata": {},
     "source": [
      "**What does this tree tell you about your data?**\n",
      "\n",
      "- Years is the most important factor determining Salary, with a lower number of Years corresponding to a lower Salary.\n",
      "- For a player with a lower number of Years, Hits is not an important factor determining Salary.\n",
      "- For a player with a higher number of Years, Hits is an important factor determining Salary, with a greater number of Hits corresponding to a higher Salary.\n",
      "\n",
      "**Question:** What do you like and dislike about decision trees so far?"
     ]
    },
    {
     "cell_type": "markdown",
     "metadata": {},
     "source": [
      "## Building a regression tree by hand\n",
      "\n",
      "Your **training data** is a tiny dataset of [used vehicle sale prices](https://raw.githubusercontent.com/justmarkham/DAT7/master/data/vehicles_train.csv). Your goal is to **predict price** for testing data.\n",
      "\n",
      "1. Read the data into a Pandas DataFrame.\n",
      "2. Explore the data by sorting, plotting, or split-apply-combine (aka `group_by`).\n",
      "3. Decide which feature is the most important predictor, and use that to create your first splitting rule.\n",
      "    - Only binary splits are allowed.\n",
      "4. After making your first split, split your DataFrame into two parts, and then explore each part to figure out what other splits to make.\n",
      "5. Stop making splits once you are convinced that it strikes a good balance between underfitting and overfitting.\n",
      "    - Your goal is to build a model that generalizes well.\n",
      "    - You are allowed to split on the same variable multiple times!\n",
      "6. Draw your tree, labeling the leaves with the mean price for the observations in that region.\n",
      "    - Make sure nothing is backwards: You follow the **left branch** if the rule is true, and the **right branch** if the rule is false."
     ]
    },
    {
     "cell_type": "markdown",
     "metadata": {},
     "source": [
      "## How does a computer build a regression tree?\n",
      "\n",
      "**Ideal approach:** Consider every possible partition of the feature space (computationally infeasible)\n",
      "\n",
      "**\"Good enough\" approach:** recursive binary splitting\n",
      "\n",
      "1. Begin at the top of the tree.\n",
      "2. For **every feature**, examine **every possible cutpoint**, and choose the feature and cutpoint such that the resulting tree has the lowest possible mean squared error (MSE). Make that split.\n",
      "3. Examine the two resulting regions, and again make a **single split** (in one of the regions) to minimize the MSE.\n",
      "4. Keep repeating step 3 until a **stopping criterion** is met:\n",
      "    - maximum tree depth (maximum number of splits required to arrive at a leaf)\n",
      "    - minimum number of observations in a leaf"
     ]
    },
    {
     "cell_type": "markdown",
     "metadata": {},
     "source": [
      "### Demo: Choosing the ideal cutpoint for a given feature"
     ]
    },
    {
     "cell_type": "code",
     "collapsed": false,
     "input": [
      "# vehicle data\n",
      "import pandas as pd\n",
      "url = 'https://raw.githubusercontent.com/justmarkham/DAT7/master/data/vehicles_train.csv'\n",
      "train = pd.read_csv(url)"
     ],
     "language": "python",
     "metadata": {},
     "outputs": [],
     "prompt_number": 1
    },
    {
     "cell_type": "code",
     "collapsed": false,
     "input": [
      "# before splitting anything, just predict the mean of the entire dataset\n",
      "train['prediction'] = train.price.mean()\n",
      "train"
     ],
     "language": "python",
     "metadata": {},
     "outputs": [
      {
       "html": [
        "<div style=\"max-width:1500px;overflow:auto;\">\n",
        "<table border=\"1\" class=\"dataframe\">\n",
        "  <thead>\n",
        "    <tr style=\"text-align: right;\">\n",
        "      <th></th>\n",
        "      <th>price</th>\n",
        "      <th>year</th>\n",
        "      <th>miles</th>\n",
        "      <th>doors</th>\n",
        "      <th>vtype</th>\n",
        "      <th>prediction</th>\n",
        "    </tr>\n",
        "  </thead>\n",
        "  <tbody>\n",
        "    <tr>\n",
        "      <th>0</th>\n",
        "      <td>22000</td>\n",
        "      <td>2012</td>\n",
        "      <td>13000</td>\n",
        "      <td>2</td>\n",
        "      <td>car</td>\n",
        "      <td>6571.428571</td>\n",
        "    </tr>\n",
        "    <tr>\n",
        "      <th>1</th>\n",
        "      <td>14000</td>\n",
        "      <td>2010</td>\n",
        "      <td>30000</td>\n",
        "      <td>2</td>\n",
        "      <td>car</td>\n",
        "      <td>6571.428571</td>\n",
        "    </tr>\n",
        "    <tr>\n",
        "      <th>2</th>\n",
        "      <td>13000</td>\n",
        "      <td>2010</td>\n",
        "      <td>73500</td>\n",
        "      <td>4</td>\n",
        "      <td>car</td>\n",
        "      <td>6571.428571</td>\n",
        "    </tr>\n",
        "    <tr>\n",
        "      <th>3</th>\n",
        "      <td>9500</td>\n",
        "      <td>2009</td>\n",
        "      <td>78000</td>\n",
        "      <td>4</td>\n",
        "      <td>car</td>\n",
        "      <td>6571.428571</td>\n",
        "    </tr>\n",
        "    <tr>\n",
        "      <th>4</th>\n",
        "      <td>9000</td>\n",
        "      <td>2007</td>\n",
        "      <td>47000</td>\n",
        "      <td>4</td>\n",
        "      <td>car</td>\n",
        "      <td>6571.428571</td>\n",
        "    </tr>\n",
        "    <tr>\n",
        "      <th>5</th>\n",
        "      <td>4000</td>\n",
        "      <td>2006</td>\n",
        "      <td>124000</td>\n",
        "      <td>2</td>\n",
        "      <td>car</td>\n",
        "      <td>6571.428571</td>\n",
        "    </tr>\n",
        "    <tr>\n",
        "      <th>6</th>\n",
        "      <td>3000</td>\n",
        "      <td>2004</td>\n",
        "      <td>177000</td>\n",
        "      <td>4</td>\n",
        "      <td>car</td>\n",
        "      <td>6571.428571</td>\n",
        "    </tr>\n",
        "    <tr>\n",
        "      <th>7</th>\n",
        "      <td>2000</td>\n",
        "      <td>2004</td>\n",
        "      <td>209000</td>\n",
        "      <td>4</td>\n",
        "      <td>truck</td>\n",
        "      <td>6571.428571</td>\n",
        "    </tr>\n",
        "    <tr>\n",
        "      <th>8</th>\n",
        "      <td>3000</td>\n",
        "      <td>2003</td>\n",
        "      <td>138000</td>\n",
        "      <td>2</td>\n",
        "      <td>car</td>\n",
        "      <td>6571.428571</td>\n",
        "    </tr>\n",
        "    <tr>\n",
        "      <th>9</th>\n",
        "      <td>1900</td>\n",
        "      <td>2003</td>\n",
        "      <td>160000</td>\n",
        "      <td>4</td>\n",
        "      <td>car</td>\n",
        "      <td>6571.428571</td>\n",
        "    </tr>\n",
        "    <tr>\n",
        "      <th>10</th>\n",
        "      <td>2500</td>\n",
        "      <td>2003</td>\n",
        "      <td>190000</td>\n",
        "      <td>2</td>\n",
        "      <td>truck</td>\n",
        "      <td>6571.428571</td>\n",
        "    </tr>\n",
        "    <tr>\n",
        "      <th>11</th>\n",
        "      <td>5000</td>\n",
        "      <td>2001</td>\n",
        "      <td>62000</td>\n",
        "      <td>4</td>\n",
        "      <td>car</td>\n",
        "      <td>6571.428571</td>\n",
        "    </tr>\n",
        "    <tr>\n",
        "      <th>12</th>\n",
        "      <td>1800</td>\n",
        "      <td>1999</td>\n",
        "      <td>163000</td>\n",
        "      <td>2</td>\n",
        "      <td>truck</td>\n",
        "      <td>6571.428571</td>\n",
        "    </tr>\n",
        "    <tr>\n",
        "      <th>13</th>\n",
        "      <td>1300</td>\n",
        "      <td>1997</td>\n",
        "      <td>138000</td>\n",
        "      <td>4</td>\n",
        "      <td>car</td>\n",
        "      <td>6571.428571</td>\n",
        "    </tr>\n",
        "  </tbody>\n",
        "</table>\n",
        "</div>"
       ],
       "metadata": {},
       "output_type": "pyout",
       "prompt_number": 2,
       "text": [
        "    price  year   miles  doors  vtype   prediction\n",
        "0   22000  2012   13000      2    car  6571.428571\n",
        "1   14000  2010   30000      2    car  6571.428571\n",
        "2   13000  2010   73500      4    car  6571.428571\n",
        "3    9500  2009   78000      4    car  6571.428571\n",
        "4    9000  2007   47000      4    car  6571.428571\n",
        "5    4000  2006  124000      2    car  6571.428571\n",
        "6    3000  2004  177000      4    car  6571.428571\n",
        "7    2000  2004  209000      4  truck  6571.428571\n",
        "8    3000  2003  138000      2    car  6571.428571\n",
        "9    1900  2003  160000      4    car  6571.428571\n",
        "10   2500  2003  190000      2  truck  6571.428571\n",
        "11   5000  2001   62000      4    car  6571.428571\n",
        "12   1800  1999  163000      2  truck  6571.428571\n",
        "13   1300  1997  138000      4    car  6571.428571"
       ]
      }
     ],
     "prompt_number": 2
    },
    {
     "cell_type": "code",
     "collapsed": false,
     "input": [
      "# calculate RMSE for those predictions\n",
      "from sklearn import metrics\n",
      "import numpy as np\n",
      "np.sqrt(metrics.mean_squared_error(train.price, train.prediction))"
     ],
     "language": "python",
     "metadata": {},
     "outputs": [
      {
       "metadata": {},
       "output_type": "pyout",
       "prompt_number": 3,
       "text": [
        "5936.9819859959835"
       ]
      }
     ],
     "prompt_number": 3
    },
    {
     "cell_type": "code",
     "collapsed": false,
     "input": [
      "# define a function that calculates the RMSE for a given split of miles\n",
      "def mileage_split(miles):\n",
      "    lower_mileage_price = train[train.miles < miles].price.mean()\n",
      "    higher_mileage_price = train[train.miles >= miles].price.mean()\n",
      "    train['prediction'] = np.where(train.miles < miles, lower_mileage_price, higher_mileage_price)\n",
      "    return np.sqrt(metrics.mean_squared_error(train.price, train.prediction))"
     ],
     "language": "python",
     "metadata": {},
     "outputs": [],
     "prompt_number": 4
    },
    {
     "cell_type": "code",
     "collapsed": false,
     "input": [
      "# calculate RMSE for tree which splits on miles < 50000\n",
      "print 'RMSE:', mileage_split(50000)\n",
      "train"
     ],
     "language": "python",
     "metadata": {},
     "outputs": [
      {
       "output_type": "stream",
       "stream": "stdout",
       "text": [
        "RMSE: 3984.09174254\n"
       ]
      },
      {
       "html": [
        "<div style=\"max-width:1500px;overflow:auto;\">\n",
        "<table border=\"1\" class=\"dataframe\">\n",
        "  <thead>\n",
        "    <tr style=\"text-align: right;\">\n",
        "      <th></th>\n",
        "      <th>price</th>\n",
        "      <th>year</th>\n",
        "      <th>miles</th>\n",
        "      <th>doors</th>\n",
        "      <th>vtype</th>\n",
        "      <th>prediction</th>\n",
        "    </tr>\n",
        "  </thead>\n",
        "  <tbody>\n",
        "    <tr>\n",
        "      <th>0</th>\n",
        "      <td>22000</td>\n",
        "      <td>2012</td>\n",
        "      <td>13000</td>\n",
        "      <td>2</td>\n",
        "      <td>car</td>\n",
        "      <td>15000.000000</td>\n",
        "    </tr>\n",
        "    <tr>\n",
        "      <th>1</th>\n",
        "      <td>14000</td>\n",
        "      <td>2010</td>\n",
        "      <td>30000</td>\n",
        "      <td>2</td>\n",
        "      <td>car</td>\n",
        "      <td>15000.000000</td>\n",
        "    </tr>\n",
        "    <tr>\n",
        "      <th>2</th>\n",
        "      <td>13000</td>\n",
        "      <td>2010</td>\n",
        "      <td>73500</td>\n",
        "      <td>4</td>\n",
        "      <td>car</td>\n",
        "      <td>4272.727273</td>\n",
        "    </tr>\n",
        "    <tr>\n",
        "      <th>3</th>\n",
        "      <td>9500</td>\n",
        "      <td>2009</td>\n",
        "      <td>78000</td>\n",
        "      <td>4</td>\n",
        "      <td>car</td>\n",
        "      <td>4272.727273</td>\n",
        "    </tr>\n",
        "    <tr>\n",
        "      <th>4</th>\n",
        "      <td>9000</td>\n",
        "      <td>2007</td>\n",
        "      <td>47000</td>\n",
        "      <td>4</td>\n",
        "      <td>car</td>\n",
        "      <td>15000.000000</td>\n",
        "    </tr>\n",
        "    <tr>\n",
        "      <th>5</th>\n",
        "      <td>4000</td>\n",
        "      <td>2006</td>\n",
        "      <td>124000</td>\n",
        "      <td>2</td>\n",
        "      <td>car</td>\n",
        "      <td>4272.727273</td>\n",
        "    </tr>\n",
        "    <tr>\n",
        "      <th>6</th>\n",
        "      <td>3000</td>\n",
        "      <td>2004</td>\n",
        "      <td>177000</td>\n",
        "      <td>4</td>\n",
        "      <td>car</td>\n",
        "      <td>4272.727273</td>\n",
        "    </tr>\n",
        "    <tr>\n",
        "      <th>7</th>\n",
        "      <td>2000</td>\n",
        "      <td>2004</td>\n",
        "      <td>209000</td>\n",
        "      <td>4</td>\n",
        "      <td>truck</td>\n",
        "      <td>4272.727273</td>\n",
        "    </tr>\n",
        "    <tr>\n",
        "      <th>8</th>\n",
        "      <td>3000</td>\n",
        "      <td>2003</td>\n",
        "      <td>138000</td>\n",
        "      <td>2</td>\n",
        "      <td>car</td>\n",
        "      <td>4272.727273</td>\n",
        "    </tr>\n",
        "    <tr>\n",
        "      <th>9</th>\n",
        "      <td>1900</td>\n",
        "      <td>2003</td>\n",
        "      <td>160000</td>\n",
        "      <td>4</td>\n",
        "      <td>car</td>\n",
        "      <td>4272.727273</td>\n",
        "    </tr>\n",
        "    <tr>\n",
        "      <th>10</th>\n",
        "      <td>2500</td>\n",
        "      <td>2003</td>\n",
        "      <td>190000</td>\n",
        "      <td>2</td>\n",
        "      <td>truck</td>\n",
        "      <td>4272.727273</td>\n",
        "    </tr>\n",
        "    <tr>\n",
        "      <th>11</th>\n",
        "      <td>5000</td>\n",
        "      <td>2001</td>\n",
        "      <td>62000</td>\n",
        "      <td>4</td>\n",
        "      <td>car</td>\n",
        "      <td>4272.727273</td>\n",
        "    </tr>\n",
        "    <tr>\n",
        "      <th>12</th>\n",
        "      <td>1800</td>\n",
        "      <td>1999</td>\n",
        "      <td>163000</td>\n",
        "      <td>2</td>\n",
        "      <td>truck</td>\n",
        "      <td>4272.727273</td>\n",
        "    </tr>\n",
        "    <tr>\n",
        "      <th>13</th>\n",
        "      <td>1300</td>\n",
        "      <td>1997</td>\n",
        "      <td>138000</td>\n",
        "      <td>4</td>\n",
        "      <td>car</td>\n",
        "      <td>4272.727273</td>\n",
        "    </tr>\n",
        "  </tbody>\n",
        "</table>\n",
        "</div>"
       ],
       "metadata": {},
       "output_type": "pyout",
       "prompt_number": 5,
       "text": [
        "    price  year   miles  doors  vtype    prediction\n",
        "0   22000  2012   13000      2    car  15000.000000\n",
        "1   14000  2010   30000      2    car  15000.000000\n",
        "2   13000  2010   73500      4    car   4272.727273\n",
        "3    9500  2009   78000      4    car   4272.727273\n",
        "4    9000  2007   47000      4    car  15000.000000\n",
        "5    4000  2006  124000      2    car   4272.727273\n",
        "6    3000  2004  177000      4    car   4272.727273\n",
        "7    2000  2004  209000      4  truck   4272.727273\n",
        "8    3000  2003  138000      2    car   4272.727273\n",
        "9    1900  2003  160000      4    car   4272.727273\n",
        "10   2500  2003  190000      2  truck   4272.727273\n",
        "11   5000  2001   62000      4    car   4272.727273\n",
        "12   1800  1999  163000      2  truck   4272.727273\n",
        "13   1300  1997  138000      4    car   4272.727273"
       ]
      }
     ],
     "prompt_number": 5
    },
    {
     "cell_type": "code",
     "collapsed": false,
     "input": [
      "# calculate RMSE for tree which splits on miles < 100000\n",
      "print 'RMSE:', mileage_split(100000)\n",
      "train"
     ],
     "language": "python",
     "metadata": {},
     "outputs": [
      {
       "output_type": "stream",
       "stream": "stdout",
       "text": [
        "RMSE: 3530.14653008\n"
       ]
      },
      {
       "html": [
        "<div style=\"max-width:1500px;overflow:auto;\">\n",
        "<table border=\"1\" class=\"dataframe\">\n",
        "  <thead>\n",
        "    <tr style=\"text-align: right;\">\n",
        "      <th></th>\n",
        "      <th>price</th>\n",
        "      <th>year</th>\n",
        "      <th>miles</th>\n",
        "      <th>doors</th>\n",
        "      <th>vtype</th>\n",
        "      <th>prediction</th>\n",
        "    </tr>\n",
        "  </thead>\n",
        "  <tbody>\n",
        "    <tr>\n",
        "      <th>0</th>\n",
        "      <td>22000</td>\n",
        "      <td>2012</td>\n",
        "      <td>13000</td>\n",
        "      <td>2</td>\n",
        "      <td>car</td>\n",
        "      <td>12083.333333</td>\n",
        "    </tr>\n",
        "    <tr>\n",
        "      <th>1</th>\n",
        "      <td>14000</td>\n",
        "      <td>2010</td>\n",
        "      <td>30000</td>\n",
        "      <td>2</td>\n",
        "      <td>car</td>\n",
        "      <td>12083.333333</td>\n",
        "    </tr>\n",
        "    <tr>\n",
        "      <th>2</th>\n",
        "      <td>13000</td>\n",
        "      <td>2010</td>\n",
        "      <td>73500</td>\n",
        "      <td>4</td>\n",
        "      <td>car</td>\n",
        "      <td>12083.333333</td>\n",
        "    </tr>\n",
        "    <tr>\n",
        "      <th>3</th>\n",
        "      <td>9500</td>\n",
        "      <td>2009</td>\n",
        "      <td>78000</td>\n",
        "      <td>4</td>\n",
        "      <td>car</td>\n",
        "      <td>12083.333333</td>\n",
        "    </tr>\n",
        "    <tr>\n",
        "      <th>4</th>\n",
        "      <td>9000</td>\n",
        "      <td>2007</td>\n",
        "      <td>47000</td>\n",
        "      <td>4</td>\n",
        "      <td>car</td>\n",
        "      <td>12083.333333</td>\n",
        "    </tr>\n",
        "    <tr>\n",
        "      <th>5</th>\n",
        "      <td>4000</td>\n",
        "      <td>2006</td>\n",
        "      <td>124000</td>\n",
        "      <td>2</td>\n",
        "      <td>car</td>\n",
        "      <td>2437.500000</td>\n",
        "    </tr>\n",
        "    <tr>\n",
        "      <th>6</th>\n",
        "      <td>3000</td>\n",
        "      <td>2004</td>\n",
        "      <td>177000</td>\n",
        "      <td>4</td>\n",
        "      <td>car</td>\n",
        "      <td>2437.500000</td>\n",
        "    </tr>\n",
        "    <tr>\n",
        "      <th>7</th>\n",
        "      <td>2000</td>\n",
        "      <td>2004</td>\n",
        "      <td>209000</td>\n",
        "      <td>4</td>\n",
        "      <td>truck</td>\n",
        "      <td>2437.500000</td>\n",
        "    </tr>\n",
        "    <tr>\n",
        "      <th>8</th>\n",
        "      <td>3000</td>\n",
        "      <td>2003</td>\n",
        "      <td>138000</td>\n",
        "      <td>2</td>\n",
        "      <td>car</td>\n",
        "      <td>2437.500000</td>\n",
        "    </tr>\n",
        "    <tr>\n",
        "      <th>9</th>\n",
        "      <td>1900</td>\n",
        "      <td>2003</td>\n",
        "      <td>160000</td>\n",
        "      <td>4</td>\n",
        "      <td>car</td>\n",
        "      <td>2437.500000</td>\n",
        "    </tr>\n",
        "    <tr>\n",
        "      <th>10</th>\n",
        "      <td>2500</td>\n",
        "      <td>2003</td>\n",
        "      <td>190000</td>\n",
        "      <td>2</td>\n",
        "      <td>truck</td>\n",
        "      <td>2437.500000</td>\n",
        "    </tr>\n",
        "    <tr>\n",
        "      <th>11</th>\n",
        "      <td>5000</td>\n",
        "      <td>2001</td>\n",
        "      <td>62000</td>\n",
        "      <td>4</td>\n",
        "      <td>car</td>\n",
        "      <td>12083.333333</td>\n",
        "    </tr>\n",
        "    <tr>\n",
        "      <th>12</th>\n",
        "      <td>1800</td>\n",
        "      <td>1999</td>\n",
        "      <td>163000</td>\n",
        "      <td>2</td>\n",
        "      <td>truck</td>\n",
        "      <td>2437.500000</td>\n",
        "    </tr>\n",
        "    <tr>\n",
        "      <th>13</th>\n",
        "      <td>1300</td>\n",
        "      <td>1997</td>\n",
        "      <td>138000</td>\n",
        "      <td>4</td>\n",
        "      <td>car</td>\n",
        "      <td>2437.500000</td>\n",
        "    </tr>\n",
        "  </tbody>\n",
        "</table>\n",
        "</div>"
       ],
       "metadata": {},
       "output_type": "pyout",
       "prompt_number": 6,
       "text": [
        "    price  year   miles  doors  vtype    prediction\n",
        "0   22000  2012   13000      2    car  12083.333333\n",
        "1   14000  2010   30000      2    car  12083.333333\n",
        "2   13000  2010   73500      4    car  12083.333333\n",
        "3    9500  2009   78000      4    car  12083.333333\n",
        "4    9000  2007   47000      4    car  12083.333333\n",
        "5    4000  2006  124000      2    car   2437.500000\n",
        "6    3000  2004  177000      4    car   2437.500000\n",
        "7    2000  2004  209000      4  truck   2437.500000\n",
        "8    3000  2003  138000      2    car   2437.500000\n",
        "9    1900  2003  160000      4    car   2437.500000\n",
        "10   2500  2003  190000      2  truck   2437.500000\n",
        "11   5000  2001   62000      4    car  12083.333333\n",
        "12   1800  1999  163000      2  truck   2437.500000\n",
        "13   1300  1997  138000      4    car   2437.500000"
       ]
      }
     ],
     "prompt_number": 6
    },
    {
     "cell_type": "code",
     "collapsed": false,
     "input": [
      "# check all possible mileage splits\n",
      "mileage_range = range(train.miles.min(), train.miles.max(), 1000)\n",
      "RMSE = [mileage_split(miles) for miles in mileage_range]\n",
      "\n",
      "# plot mileage cutpoint (x-axis) versus RMSE (y-axis)\n",
      "%matplotlib inline\n",
      "import matplotlib.pyplot as plt\n",
      "plt.plot(mileage_range, RMSE)\n",
      "plt.xlabel('Mileage cutpoint')\n",
      "plt.ylabel('RMSE (lower is better)')"
     ],
     "language": "python",
     "metadata": {},
     "outputs": [
      {
       "metadata": {},
       "output_type": "pyout",
       "prompt_number": 7,
       "text": [
        "<matplotlib.text.Text at 0x1745a780>"
       ]
      },
      {
       "metadata": {},
       "output_type": "display_data",
       "png": "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\n",
       "text": [
        "<matplotlib.figure.Figure at 0x1730a9b0>"
       ]
      }
     ],
     "prompt_number": 7
    },
    {
     "cell_type": "markdown",
     "metadata": {},
     "source": [
      "**Recap:** Before every split, this process is repeated for every feature, and the feature and cutpoint that produces the lowest MSE is chosen."
     ]
    },
    {
     "cell_type": "markdown",
     "metadata": {},
     "source": [
      "## Building a regression tree in scikit-learn"
     ]
    },
    {
     "cell_type": "code",
     "collapsed": false,
     "input": [
      "# encode car as 0 and truck as 1\n",
      "train['vtype'] = train.vtype.map({'car':0, 'truck':1})"
     ],
     "language": "python",
     "metadata": {},
     "outputs": [],
     "prompt_number": 8
    },
    {
     "cell_type": "code",
     "collapsed": false,
     "input": [
      "# define X and y\n",
      "feature_cols = ['year', 'miles', 'doors', 'vtype']\n",
      "X = train[feature_cols]\n",
      "y = train.price"
     ],
     "language": "python",
     "metadata": {},
     "outputs": [],
     "prompt_number": 9
    },
    {
     "cell_type": "code",
     "collapsed": false,
     "input": [
      "# instantiate a DecisionTreeRegressor (with random_state=1)\n",
      "from sklearn.tree import DecisionTreeRegressor\n",
      "treereg = DecisionTreeRegressor(random_state=1)\n",
      "treereg"
     ],
     "language": "python",
     "metadata": {},
     "outputs": [
      {
       "metadata": {},
       "output_type": "pyout",
       "prompt_number": 10,
       "text": [
        "DecisionTreeRegressor(compute_importances=None, criterion='mse',\n",
        "           max_depth=None, max_features=None, max_leaf_nodes=None,\n",
        "           min_density=None, min_samples_leaf=1, min_samples_split=2,\n",
        "           random_state=1, splitter='best')"
       ]
      }
     ],
     "prompt_number": 10
    },
    {
     "cell_type": "code",
     "collapsed": false,
     "input": [
      "# use leave-one-out cross-validation (LOOCV) to estimate the RMSE for this model\n",
      "from sklearn.cross_validation import cross_val_score\n",
      "scores = cross_val_score(treereg, X, y, cv=14, scoring='mean_squared_error')\n",
      "np.mean(np.sqrt(-scores))"
     ],
     "language": "python",
     "metadata": {},
     "outputs": [
      {
       "metadata": {},
       "output_type": "pyout",
       "prompt_number": 11,
       "text": [
        "2928.5714285714284"
       ]
      }
     ],
     "prompt_number": 11
    },
    {
     "cell_type": "markdown",
     "metadata": {},
     "source": [
      "## What happens when we grow a tree too deep?\n",
      "\n",
      "- Left: Regression tree for Salary **grown deeper**\n",
      "- Right: Comparison of the **training, testing, and cross-validation errors** for trees with different numbers of leaves"
     ]
    },
    {
     "cell_type": "markdown",
     "metadata": {},
     "source": [
      "![Salary tree grown deep](images/salary_tree_deep.png)"
     ]
    },
    {
     "cell_type": "markdown",
     "metadata": {},
     "source": [
      "The **training error** continues to go down as the tree size increases (due to overfitting), but the lowest **cross-validation error** occurs for a tree with 3 leaves."
     ]
    },
    {
     "cell_type": "markdown",
     "metadata": {},
     "source": [
      "## Tuning a regression tree\n",
      "\n",
      "Let's try to reduce the RMSE by tuning the **max_depth** parameter:"
     ]
    },
    {
     "cell_type": "code",
     "collapsed": false,
     "input": [
      "# try different values one-by-one\n",
      "treereg = DecisionTreeRegressor(max_depth=1, random_state=1)\n",
      "scores = cross_val_score(treereg, X, y, cv=14, scoring='mean_squared_error')\n",
      "np.mean(np.sqrt(-scores))"
     ],
     "language": "python",
     "metadata": {},
     "outputs": [
      {
       "metadata": {},
       "output_type": "pyout",
       "prompt_number": 12,
       "text": [
        "3757.936507936508"
       ]
      }
     ],
     "prompt_number": 12
    },
    {
     "cell_type": "markdown",
     "metadata": {},
     "source": [
      "Or, we could write a loop to try a range of values:"
     ]
    },
    {
     "cell_type": "code",
     "collapsed": false,
     "input": [
      "# list of values to try\n",
      "max_depth_range = range(1, 8)\n",
      "\n",
      "# list to store the average RMSE for each value of max_depth\n",
      "RMSE_scores = []\n",
      "\n",
      "# use LOOCV with each value of max_depth\n",
      "for depth in max_depth_range:\n",
      "    treereg = DecisionTreeRegressor(max_depth=depth, random_state=1)\n",
      "    MSE_scores = cross_val_score(treereg, X, y, cv=14, scoring='mean_squared_error')\n",
      "    RMSE_scores.append(np.mean(np.sqrt(-MSE_scores)))\n",
      "\n",
      "# plot max_depth (x-axis) versus RMSE (y-axis)\n",
      "plt.plot(max_depth_range, RMSE_scores)\n",
      "plt.xlabel('max_depth')\n",
      "plt.ylabel('RMSE (lower is better)')"
     ],
     "language": "python",
     "metadata": {},
     "outputs": [
      {
       "metadata": {},
       "output_type": "pyout",
       "prompt_number": 13,
       "text": [
        "<matplotlib.text.Text at 0x17d4a908>"
       ]
      },
      {
       "metadata": {},
       "output_type": "display_data",
       "png": "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\nAAAASUVORK5CYII=\n",
       "text": [
        "<matplotlib.figure.Figure at 0x2d685f8>"
       ]
      }
     ],
     "prompt_number": 13
    },
    {
     "cell_type": "code",
     "collapsed": false,
     "input": [
      "# max_depth=3 was best, so fit a tree using that parameter\n",
      "treereg = DecisionTreeRegressor(max_depth=3, random_state=1)\n",
      "treereg.fit(X, y)"
     ],
     "language": "python",
     "metadata": {},
     "outputs": [
      {
       "metadata": {},
       "output_type": "pyout",
       "prompt_number": 14,
       "text": [
        "DecisionTreeRegressor(compute_importances=None, criterion='mse', max_depth=3,\n",
        "           max_features=None, max_leaf_nodes=None, min_density=None,\n",
        "           min_samples_leaf=1, min_samples_split=2, random_state=1,\n",
        "           splitter='best')"
       ]
      }
     ],
     "prompt_number": 14
    },
    {
     "cell_type": "code",
     "collapsed": false,
     "input": [
      "# \"Gini importance\" of each feature: the (normalized) total reduction of error brought by that feature\n",
      "pd.DataFrame({'feature':feature_cols, 'importance':treereg.feature_importances_})"
     ],
     "language": "python",
     "metadata": {},
     "outputs": [
      {
       "html": [
        "<div style=\"max-width:1500px;overflow:auto;\">\n",
        "<table border=\"1\" class=\"dataframe\">\n",
        "  <thead>\n",
        "    <tr style=\"text-align: right;\">\n",
        "      <th></th>\n",
        "      <th>feature</th>\n",
        "      <th>importance</th>\n",
        "    </tr>\n",
        "  </thead>\n",
        "  <tbody>\n",
        "    <tr>\n",
        "      <th>0</th>\n",
        "      <td>year</td>\n",
        "      <td>0.798744</td>\n",
        "    </tr>\n",
        "    <tr>\n",
        "      <th>1</th>\n",
        "      <td>miles</td>\n",
        "      <td>0.201256</td>\n",
        "    </tr>\n",
        "    <tr>\n",
        "      <th>2</th>\n",
        "      <td>doors</td>\n",
        "      <td>0.000000</td>\n",
        "    </tr>\n",
        "    <tr>\n",
        "      <th>3</th>\n",
        "      <td>vtype</td>\n",
        "      <td>0.000000</td>\n",
        "    </tr>\n",
        "  </tbody>\n",
        "</table>\n",
        "</div>"
       ],
       "metadata": {},
       "output_type": "pyout",
       "prompt_number": 15,
       "text": [
        "  feature  importance\n",
        "0    year    0.798744\n",
        "1   miles    0.201256\n",
        "2   doors    0.000000\n",
        "3   vtype    0.000000"
       ]
      }
     ],
     "prompt_number": 15
    },
    {
     "cell_type": "markdown",
     "metadata": {},
     "source": [
      "## Creating a tree diagram"
     ]
    },
    {
     "cell_type": "code",
     "collapsed": false,
     "input": [
      "# create a GraphViz file\n",
      "from sklearn.tree import export_graphviz\n",
      "export_graphviz(treereg, out_file='tree_vehicles.dot', feature_names=feature_cols)\n",
      "\n",
      "# At the command line, run this to convert to PNG:\n",
      "# dot -Tpng tree_vehicles.dot -o tree_vehicles.png"
     ],
     "language": "python",
     "metadata": {},
     "outputs": [],
     "prompt_number": 16
    },
    {
     "cell_type": "markdown",
     "metadata": {},
     "source": [
      "![Tree for vehicle data](images/tree_vehicles.png)"
     ]
    },
    {
     "cell_type": "markdown",
     "metadata": {},
     "source": [
      "Reading the internal nodes:\n",
      "\n",
      "- **samples:** number of observations in that node before splitting\n",
      "- **mse:** MSE calculated by comparing the actual response values in that node against the mean response value in that node\n",
      "- **rule:** rule used to split that node (go left if true, go right if false)\n",
      "\n",
      "Reading the leaves:\n",
      "\n",
      "- **samples:** number of observations in that node\n",
      "- **value:** mean response value in that node\n",
      "- **mse:** MSE calculated by comparing the actual response values in that node against \"value\""
     ]
    },
    {
     "cell_type": "markdown",
     "metadata": {},
     "source": [
      "## Making predictions for the testing data"
     ]
    },
    {
     "cell_type": "code",
     "collapsed": false,
     "input": [
      "# read the testing data\n",
      "url = 'https://raw.githubusercontent.com/justmarkham/DAT7/master/data/vehicles_test.csv'\n",
      "test = pd.read_csv(url)\n",
      "test['vtype'] = test.vtype.map({'car':0, 'truck':1})\n",
      "test"
     ],
     "language": "python",
     "metadata": {},
     "outputs": [
      {
       "html": [
        "<div style=\"max-width:1500px;overflow:auto;\">\n",
        "<table border=\"1\" class=\"dataframe\">\n",
        "  <thead>\n",
        "    <tr style=\"text-align: right;\">\n",
        "      <th></th>\n",
        "      <th>price</th>\n",
        "      <th>year</th>\n",
        "      <th>miles</th>\n",
        "      <th>doors</th>\n",
        "      <th>vtype</th>\n",
        "    </tr>\n",
        "  </thead>\n",
        "  <tbody>\n",
        "    <tr>\n",
        "      <th>0</th>\n",
        "      <td>3000</td>\n",
        "      <td>2003</td>\n",
        "      <td>130000</td>\n",
        "      <td>4</td>\n",
        "      <td>1</td>\n",
        "    </tr>\n",
        "    <tr>\n",
        "      <th>1</th>\n",
        "      <td>6000</td>\n",
        "      <td>2005</td>\n",
        "      <td>82500</td>\n",
        "      <td>4</td>\n",
        "      <td>0</td>\n",
        "    </tr>\n",
        "    <tr>\n",
        "      <th>2</th>\n",
        "      <td>12000</td>\n",
        "      <td>2010</td>\n",
        "      <td>60000</td>\n",
        "      <td>2</td>\n",
        "      <td>0</td>\n",
        "    </tr>\n",
        "  </tbody>\n",
        "</table>\n",
        "</div>"
       ],
       "metadata": {},
       "output_type": "pyout",
       "prompt_number": 17,
       "text": [
        "   price  year   miles  doors  vtype\n",
        "0   3000  2003  130000      4      1\n",
        "1   6000  2005   82500      4      0\n",
        "2  12000  2010   60000      2      0"
       ]
      }
     ],
     "prompt_number": 17
    },
    {
     "cell_type": "markdown",
     "metadata": {},
     "source": [
      "**Question:** Using the tree diagram above, what predictions will the model make for each observation?"
     ]
    },
    {
     "cell_type": "code",
     "collapsed": false,
     "input": [
      "# use fitted model to make predictions on testing data\n",
      "X_test = test[feature_cols]\n",
      "y_test = test.price\n",
      "y_pred = treereg.predict(X_test)\n",
      "y_pred"
     ],
     "language": "python",
     "metadata": {},
     "outputs": [
      {
       "metadata": {},
       "output_type": "pyout",
       "prompt_number": 18,
       "text": [
        "array([  4000.,   5000.,  13500.])"
       ]
      }
     ],
     "prompt_number": 18
    },
    {
     "cell_type": "code",
     "collapsed": false,
     "input": [
      "# calculate RMSE\n",
      "np.sqrt(metrics.mean_squared_error(y_test, y_pred))"
     ],
     "language": "python",
     "metadata": {},
     "outputs": [
      {
       "metadata": {},
       "output_type": "pyout",
       "prompt_number": 19,
       "text": [
        "1190.2380714238084"
       ]
      }
     ],
     "prompt_number": 19
    },
    {
     "cell_type": "code",
     "collapsed": false,
     "input": [
      "# calculate RMSE for your own tree!\n",
      "y_test = [3000, 6000, 12000]\n",
      "y_pred = [0, 0, 0]\n",
      "from sklearn import metrics\n",
      "np.sqrt(metrics.mean_squared_error(y_test, y_pred))"
     ],
     "language": "python",
     "metadata": {},
     "outputs": [
      {
       "metadata": {},
       "output_type": "pyout",
       "prompt_number": 20,
       "text": [
        "7937.2539331937714"
       ]
      }
     ],
     "prompt_number": 20
    },
    {
     "cell_type": "markdown",
     "metadata": {},
     "source": [
      "# Part 2: Classification trees\n",
      "\n",
      "**Example:** Predict whether Barack Obama or Hillary Clinton will win the Democratic primary in a particular county in 2008:"
     ]
    },
    {
     "cell_type": "markdown",
     "metadata": {},
     "source": [
      "![Obama-Clinton decision tree](images/obama_clinton_tree.jpg)"
     ]
    },
    {
     "cell_type": "markdown",
     "metadata": {},
     "source": [
      "**Questions:**\n",
      "\n",
      "- What are the observations? How many observations are there?\n",
      "- What is the response variable?\n",
      "- What are the features?\n",
      "- What is the most predictive feature?\n",
      "- Why does the tree split on high school graduation rate twice in a row?\n",
      "- What is the class prediction for the following county: 15% African-American, 90% high school graduation rate, located in the South, high poverty, high population density?\n",
      "- What is the predicted probability for that same county?"
     ]
    },
    {
     "cell_type": "markdown",
     "metadata": {},
     "source": [
      "## Comparing regression trees and classification trees\n",
      "\n",
      "|regression trees|classification trees|\n",
      "|---|---|\n",
      "|predict a continuous response|predict a categorical response|\n",
      "|predict using mean response of each leaf|predict using most commonly occuring class of each leaf|\n",
      "|splits are chosen to minimize MSE|splits are chosen to minimize Gini index (discussed below)|"
     ]
    },
    {
     "cell_type": "markdown",
     "metadata": {},
     "source": [
      "## Splitting criteria for classification trees\n",
      "\n",
      "Common options for the splitting criteria:\n",
      "\n",
      "- **classification error rate:** fraction of training observations in a region that don't belong to the most common class\n",
      "- **Gini index:** measure of total variance across classes in a region"
     ]
    },
    {
     "cell_type": "markdown",
     "metadata": {},
     "source": [
      "### Example of classification error rate\n",
      "\n",
      "Pretend we are predicting whether someone buys an iPhone or an Android:\n",
      "\n",
      "- At a particular node, there are **25 observations** (phone buyers), of whom **10 bought iPhones and 15 bought Androids**.\n",
      "- Since the majority class is **Android**, that's our prediction for all 25 observations, and thus the classification error rate is **10/25 = 40%**.\n",
      "\n",
      "Our goal in making splits is to **reduce the classification error rate**. Let's try splitting on gender:\n",
      "\n",
      "- **Males:** 2 iPhones and 12 Androids, thus the predicted class is Android\n",
      "- **Females:** 8 iPhones and 3 Androids, thus the predicted class is iPhone\n",
      "- Classification error rate after this split would be **5/25 = 20%**\n",
      "\n",
      "Compare that with a split on age:\n",
      "\n",
      "- **30 or younger:** 4 iPhones and 8 Androids, thus the predicted class is Android\n",
      "- **31 or older:** 6 iPhones and 7 Androids, thus the predicted class is Android\n",
      "- Classification error rate after this split would be **10/25 = 40%**\n",
      "\n",
      "The decision tree algorithm will try **every possible split across all features**, and choose the split that **reduces the error rate the most.**"
     ]
    },
    {
     "cell_type": "markdown",
     "metadata": {},
     "source": [
      "### Example of Gini index\n",
      "\n",
      "Calculate the Gini index before making a split:\n",
      "\n",
      "$$1 - \\left(\\frac {iPhone} {Total}\\right)^2 - \\left(\\frac {Android} {Total}\\right)^2 = 1 - \\left(\\frac {10} {25}\\right)^2 - \\left(\\frac {15} {25}\\right)^2 = 0.48$$\n",
      "\n",
      "- The **maximum value** of the Gini index is 0.5, and occurs when the classes are perfectly balanced in a node.\n",
      "- The **minimum value** of the Gini index is 0, and occurs when there is only one class represented in a node.\n",
      "- A node with a lower Gini index is said to be more \"pure\".\n",
      "\n",
      "Evaluating the split on **gender** using Gini index:\n",
      "\n",
      "$$\\text{Males: } 1 - \\left(\\frac {2} {14}\\right)^2 - \\left(\\frac {12} {14}\\right)^2 = 0.24$$\n",
      "$$\\text{Females: } 1 - \\left(\\frac {8} {11}\\right)^2 - \\left(\\frac {3} {11}\\right)^2 = 0.40$$\n",
      "$$\\text{Weighted Average: } 0.24 \\left(\\frac {14} {25}\\right) + 0.40 \\left(\\frac {11} {25}\\right) = 0.31$$\n",
      "\n",
      "Evaluating the split on **age** using Gini index:\n",
      "\n",
      "$$\\text{30 or younger: } 1 - \\left(\\frac {4} {12}\\right)^2 - \\left(\\frac {8} {12}\\right)^2 = 0.44$$\n",
      "$$\\text{31 or older: } 1 - \\left(\\frac {6} {13}\\right)^2 - \\left(\\frac {7} {13}\\right)^2 = 0.50$$\n",
      "$$\\text{Weighted Average: } 0.44 \\left(\\frac {12} {25}\\right) + 0.50 \\left(\\frac {13} {25}\\right) = 0.47$$\n",
      "\n",
      "Again, the decision tree algorithm will try **every possible split**, and will choose the split that **reduces the Gini index (and thus increases the \"node purity\") the most.**"
     ]
    },
    {
     "cell_type": "markdown",
     "metadata": {},
     "source": [
      "### Comparing classification error rate and Gini index\n",
      "\n",
      "- Gini index is generally preferred because it will make splits that **increase node purity**, even if that split does not change the classification error rate.\n",
      "- Node purity is important because we're interested in the **class proportions** in each region, since that's how we calculate the **predicted probability** of each class.\n",
      "- scikit-learn's default splitting criteria for classification trees is Gini index.\n",
      "\n",
      "Note: There is another common splitting criteria called **cross-entropy**. It's numerically similar to Gini index, but slower to compute, thus it's not as popular as Gini index."
     ]
    },
    {
     "cell_type": "markdown",
     "metadata": {},
     "source": [
      "## Building a classification tree in scikit-learn"
     ]
    },
    {
     "cell_type": "markdown",
     "metadata": {},
     "source": [
      "We'll build a classification tree using the Titanic data:"
     ]
    },
    {
     "cell_type": "code",
     "collapsed": false,
     "input": [
      "# read in the data\n",
      "url = 'https://raw.githubusercontent.com/justmarkham/DAT7/master/data/titanic.csv'\n",
      "titanic = pd.read_csv(url)\n",
      "titanic.head(10)"
     ],
     "language": "python",
     "metadata": {},
     "outputs": [
      {
       "html": [
        "<div style=\"max-width:1500px;overflow:auto;\">\n",
        "<table border=\"1\" class=\"dataframe\">\n",
        "  <thead>\n",
        "    <tr style=\"text-align: right;\">\n",
        "      <th></th>\n",
        "      <th>PassengerId</th>\n",
        "      <th>Survived</th>\n",
        "      <th>Pclass</th>\n",
        "      <th>Name</th>\n",
        "      <th>Sex</th>\n",
        "      <th>Age</th>\n",
        "      <th>SibSp</th>\n",
        "      <th>Parch</th>\n",
        "      <th>Ticket</th>\n",
        "      <th>Fare</th>\n",
        "      <th>Cabin</th>\n",
        "      <th>Embarked</th>\n",
        "    </tr>\n",
        "  </thead>\n",
        "  <tbody>\n",
        "    <tr>\n",
        "      <th>0</th>\n",
        "      <td>1</td>\n",
        "      <td>0</td>\n",
        "      <td>3</td>\n",
        "      <td>Braund, Mr. Owen Harris</td>\n",
        "      <td>male</td>\n",
        "      <td>22</td>\n",
        "      <td>1</td>\n",
        "      <td>0</td>\n",
        "      <td>A/5 21171</td>\n",
        "      <td>7.2500</td>\n",
        "      <td>NaN</td>\n",
        "      <td>S</td>\n",
        "    </tr>\n",
        "    <tr>\n",
        "      <th>1</th>\n",
        "      <td>2</td>\n",
        "      <td>1</td>\n",
        "      <td>1</td>\n",
        "      <td>Cumings, Mrs. John Bradley (Florence Briggs Th...</td>\n",
        "      <td>female</td>\n",
        "      <td>38</td>\n",
        "      <td>1</td>\n",
        "      <td>0</td>\n",
        "      <td>PC 17599</td>\n",
        "      <td>71.2833</td>\n",
        "      <td>C85</td>\n",
        "      <td>C</td>\n",
        "    </tr>\n",
        "    <tr>\n",
        "      <th>2</th>\n",
        "      <td>3</td>\n",
        "      <td>1</td>\n",
        "      <td>3</td>\n",
        "      <td>Heikkinen, Miss. Laina</td>\n",
        "      <td>female</td>\n",
        "      <td>26</td>\n",
        "      <td>0</td>\n",
        "      <td>0</td>\n",
        "      <td>STON/O2. 3101282</td>\n",
        "      <td>7.9250</td>\n",
        "      <td>NaN</td>\n",
        "      <td>S</td>\n",
        "    </tr>\n",
        "    <tr>\n",
        "      <th>3</th>\n",
        "      <td>4</td>\n",
        "      <td>1</td>\n",
        "      <td>1</td>\n",
        "      <td>Futrelle, Mrs. Jacques Heath (Lily May Peel)</td>\n",
        "      <td>female</td>\n",
        "      <td>35</td>\n",
        "      <td>1</td>\n",
        "      <td>0</td>\n",
        "      <td>113803</td>\n",
        "      <td>53.1000</td>\n",
        "      <td>C123</td>\n",
        "      <td>S</td>\n",
        "    </tr>\n",
        "    <tr>\n",
        "      <th>4</th>\n",
        "      <td>5</td>\n",
        "      <td>0</td>\n",
        "      <td>3</td>\n",
        "      <td>Allen, Mr. William Henry</td>\n",
        "      <td>male</td>\n",
        "      <td>35</td>\n",
        "      <td>0</td>\n",
        "      <td>0</td>\n",
        "      <td>373450</td>\n",
        "      <td>8.0500</td>\n",
        "      <td>NaN</td>\n",
        "      <td>S</td>\n",
        "    </tr>\n",
        "    <tr>\n",
        "      <th>5</th>\n",
        "      <td>6</td>\n",
        "      <td>0</td>\n",
        "      <td>3</td>\n",
        "      <td>Moran, Mr. James</td>\n",
        "      <td>male</td>\n",
        "      <td>NaN</td>\n",
        "      <td>0</td>\n",
        "      <td>0</td>\n",
        "      <td>330877</td>\n",
        "      <td>8.4583</td>\n",
        "      <td>NaN</td>\n",
        "      <td>Q</td>\n",
        "    </tr>\n",
        "    <tr>\n",
        "      <th>6</th>\n",
        "      <td>7</td>\n",
        "      <td>0</td>\n",
        "      <td>1</td>\n",
        "      <td>McCarthy, Mr. Timothy J</td>\n",
        "      <td>male</td>\n",
        "      <td>54</td>\n",
        "      <td>0</td>\n",
        "      <td>0</td>\n",
        "      <td>17463</td>\n",
        "      <td>51.8625</td>\n",
        "      <td>E46</td>\n",
        "      <td>S</td>\n",
        "    </tr>\n",
        "    <tr>\n",
        "      <th>7</th>\n",
        "      <td>8</td>\n",
        "      <td>0</td>\n",
        "      <td>3</td>\n",
        "      <td>Palsson, Master. Gosta Leonard</td>\n",
        "      <td>male</td>\n",
        "      <td>2</td>\n",
        "      <td>3</td>\n",
        "      <td>1</td>\n",
        "      <td>349909</td>\n",
        "      <td>21.0750</td>\n",
        "      <td>NaN</td>\n",
        "      <td>S</td>\n",
        "    </tr>\n",
        "    <tr>\n",
        "      <th>8</th>\n",
        "      <td>9</td>\n",
        "      <td>1</td>\n",
        "      <td>3</td>\n",
        "      <td>Johnson, Mrs. Oscar W (Elisabeth Vilhelmina Berg)</td>\n",
        "      <td>female</td>\n",
        "      <td>27</td>\n",
        "      <td>0</td>\n",
        "      <td>2</td>\n",
        "      <td>347742</td>\n",
        "      <td>11.1333</td>\n",
        "      <td>NaN</td>\n",
        "      <td>S</td>\n",
        "    </tr>\n",
        "    <tr>\n",
        "      <th>9</th>\n",
        "      <td>10</td>\n",
        "      <td>1</td>\n",
        "      <td>2</td>\n",
        "      <td>Nasser, Mrs. Nicholas (Adele Achem)</td>\n",
        "      <td>female</td>\n",
        "      <td>14</td>\n",
        "      <td>1</td>\n",
        "      <td>0</td>\n",
        "      <td>237736</td>\n",
        "      <td>30.0708</td>\n",
        "      <td>NaN</td>\n",
        "      <td>C</td>\n",
        "    </tr>\n",
        "  </tbody>\n",
        "</table>\n",
        "</div>"
       ],
       "metadata": {},
       "output_type": "pyout",
       "prompt_number": 21,
       "text": [
        "   PassengerId  Survived  Pclass  \\\n",
        "0            1         0       3   \n",
        "1            2         1       1   \n",
        "2            3         1       3   \n",
        "3            4         1       1   \n",
        "4            5         0       3   \n",
        "5            6         0       3   \n",
        "6            7         0       1   \n",
        "7            8         0       3   \n",
        "8            9         1       3   \n",
        "9           10         1       2   \n",
        "\n",
        "                                                Name     Sex  Age  SibSp  \\\n",
        "0                            Braund, Mr. Owen Harris    male   22      1   \n",
        "1  Cumings, Mrs. John Bradley (Florence Briggs Th...  female   38      1   \n",
        "2                             Heikkinen, Miss. Laina  female   26      0   \n",
        "3       Futrelle, Mrs. Jacques Heath (Lily May Peel)  female   35      1   \n",
        "4                           Allen, Mr. William Henry    male   35      0   \n",
        "5                                   Moran, Mr. James    male  NaN      0   \n",
        "6                            McCarthy, Mr. Timothy J    male   54      0   \n",
        "7                     Palsson, Master. Gosta Leonard    male    2      3   \n",
        "8  Johnson, Mrs. Oscar W (Elisabeth Vilhelmina Berg)  female   27      0   \n",
        "9                Nasser, Mrs. Nicholas (Adele Achem)  female   14      1   \n",
        "\n",
        "   Parch            Ticket     Fare Cabin Embarked  \n",
        "0      0         A/5 21171   7.2500   NaN        S  \n",
        "1      0          PC 17599  71.2833   C85        C  \n",
        "2      0  STON/O2. 3101282   7.9250   NaN        S  \n",
        "3      0            113803  53.1000  C123        S  \n",
        "4      0            373450   8.0500   NaN        S  \n",
        "5      0            330877   8.4583   NaN        Q  \n",
        "6      0             17463  51.8625   E46        S  \n",
        "7      1            349909  21.0750   NaN        S  \n",
        "8      2            347742  11.1333   NaN        S  \n",
        "9      0            237736  30.0708   NaN        C  "
       ]
      }
     ],
     "prompt_number": 21
    },
    {
     "cell_type": "markdown",
     "metadata": {},
     "source": [
      "What special handling do we need to apply (if any) to the following columns?\n",
      "\n",
      "- **Survived:** 1=survived, 0=passed away (response variable)\n",
      "- **Pclass:** 1=first class, 2=second class, 3=third class\n",
      "    - What will happen if the tree splits on this feature?\n",
      "- **Sex:** male or female\n",
      "- **Age:** numeric value\n",
      "- **Embarked:** C or Q or S"
     ]
    },
    {
     "cell_type": "code",
     "collapsed": false,
     "input": [
      "# encode female as 0 and male as 1\n",
      "titanic['Sex'] = titanic.Sex.map({'female':0, 'male':1})\n",
      "\n",
      "# fill in the missing values for age with the mean age\n",
      "titanic.Age.fillna(titanic.Age.mean(), inplace=True)\n",
      "\n",
      "# create three dummy variables, drop the first dummy variable, and store the two remaining columns as a DataFrame\n",
      "embarked_dummies = pd.get_dummies(titanic.Embarked, prefix='Embarked').iloc[:, 1:]\n",
      "\n",
      "# concatenate the two dummy variable columns onto the original DataFrame\n",
      "titanic = pd.concat([titanic, embarked_dummies], axis=1)\n",
      "\n",
      "# print the updated DataFrame\n",
      "titanic.head(10)"
     ],
     "language": "python",
     "metadata": {},
     "outputs": [
      {
       "html": [
        "<div style=\"max-width:1500px;overflow:auto;\">\n",
        "<table border=\"1\" class=\"dataframe\">\n",
        "  <thead>\n",
        "    <tr style=\"text-align: right;\">\n",
        "      <th></th>\n",
        "      <th>PassengerId</th>\n",
        "      <th>Survived</th>\n",
        "      <th>Pclass</th>\n",
        "      <th>Name</th>\n",
        "      <th>Sex</th>\n",
        "      <th>Age</th>\n",
        "      <th>SibSp</th>\n",
        "      <th>Parch</th>\n",
        "      <th>Ticket</th>\n",
        "      <th>Fare</th>\n",
        "      <th>Cabin</th>\n",
        "      <th>Embarked</th>\n",
        "      <th>Embarked_Q</th>\n",
        "      <th>Embarked_S</th>\n",
        "    </tr>\n",
        "  </thead>\n",
        "  <tbody>\n",
        "    <tr>\n",
        "      <th>0</th>\n",
        "      <td>1</td>\n",
        "      <td>0</td>\n",
        "      <td>3</td>\n",
        "      <td>Braund, Mr. Owen Harris</td>\n",
        "      <td>1</td>\n",
        "      <td>22.000000</td>\n",
        "      <td>1</td>\n",
        "      <td>0</td>\n",
        "      <td>A/5 21171</td>\n",
        "      <td>7.2500</td>\n",
        "      <td>NaN</td>\n",
        "      <td>S</td>\n",
        "      <td>0</td>\n",
        "      <td>1</td>\n",
        "    </tr>\n",
        "    <tr>\n",
        "      <th>1</th>\n",
        "      <td>2</td>\n",
        "      <td>1</td>\n",
        "      <td>1</td>\n",
        "      <td>Cumings, Mrs. John Bradley (Florence Briggs Th...</td>\n",
        "      <td>0</td>\n",
        "      <td>38.000000</td>\n",
        "      <td>1</td>\n",
        "      <td>0</td>\n",
        "      <td>PC 17599</td>\n",
        "      <td>71.2833</td>\n",
        "      <td>C85</td>\n",
        "      <td>C</td>\n",
        "      <td>0</td>\n",
        "      <td>0</td>\n",
        "    </tr>\n",
        "    <tr>\n",
        "      <th>2</th>\n",
        "      <td>3</td>\n",
        "      <td>1</td>\n",
        "      <td>3</td>\n",
        "      <td>Heikkinen, Miss. Laina</td>\n",
        "      <td>0</td>\n",
        "      <td>26.000000</td>\n",
        "      <td>0</td>\n",
        "      <td>0</td>\n",
        "      <td>STON/O2. 3101282</td>\n",
        "      <td>7.9250</td>\n",
        "      <td>NaN</td>\n",
        "      <td>S</td>\n",
        "      <td>0</td>\n",
        "      <td>1</td>\n",
        "    </tr>\n",
        "    <tr>\n",
        "      <th>3</th>\n",
        "      <td>4</td>\n",
        "      <td>1</td>\n",
        "      <td>1</td>\n",
        "      <td>Futrelle, Mrs. Jacques Heath (Lily May Peel)</td>\n",
        "      <td>0</td>\n",
        "      <td>35.000000</td>\n",
        "      <td>1</td>\n",
        "      <td>0</td>\n",
        "      <td>113803</td>\n",
        "      <td>53.1000</td>\n",
        "      <td>C123</td>\n",
        "      <td>S</td>\n",
        "      <td>0</td>\n",
        "      <td>1</td>\n",
        "    </tr>\n",
        "    <tr>\n",
        "      <th>4</th>\n",
        "      <td>5</td>\n",
        "      <td>0</td>\n",
        "      <td>3</td>\n",
        "      <td>Allen, Mr. William Henry</td>\n",
        "      <td>1</td>\n",
        "      <td>35.000000</td>\n",
        "      <td>0</td>\n",
        "      <td>0</td>\n",
        "      <td>373450</td>\n",
        "      <td>8.0500</td>\n",
        "      <td>NaN</td>\n",
        "      <td>S</td>\n",
        "      <td>0</td>\n",
        "      <td>1</td>\n",
        "    </tr>\n",
        "    <tr>\n",
        "      <th>5</th>\n",
        "      <td>6</td>\n",
        "      <td>0</td>\n",
        "      <td>3</td>\n",
        "      <td>Moran, Mr. James</td>\n",
        "      <td>1</td>\n",
        "      <td>29.699118</td>\n",
        "      <td>0</td>\n",
        "      <td>0</td>\n",
        "      <td>330877</td>\n",
        "      <td>8.4583</td>\n",
        "      <td>NaN</td>\n",
        "      <td>Q</td>\n",
        "      <td>1</td>\n",
        "      <td>0</td>\n",
        "    </tr>\n",
        "    <tr>\n",
        "      <th>6</th>\n",
        "      <td>7</td>\n",
        "      <td>0</td>\n",
        "      <td>1</td>\n",
        "      <td>McCarthy, Mr. Timothy J</td>\n",
        "      <td>1</td>\n",
        "      <td>54.000000</td>\n",
        "      <td>0</td>\n",
        "      <td>0</td>\n",
        "      <td>17463</td>\n",
        "      <td>51.8625</td>\n",
        "      <td>E46</td>\n",
        "      <td>S</td>\n",
        "      <td>0</td>\n",
        "      <td>1</td>\n",
        "    </tr>\n",
        "    <tr>\n",
        "      <th>7</th>\n",
        "      <td>8</td>\n",
        "      <td>0</td>\n",
        "      <td>3</td>\n",
        "      <td>Palsson, Master. Gosta Leonard</td>\n",
        "      <td>1</td>\n",
        "      <td>2.000000</td>\n",
        "      <td>3</td>\n",
        "      <td>1</td>\n",
        "      <td>349909</td>\n",
        "      <td>21.0750</td>\n",
        "      <td>NaN</td>\n",
        "      <td>S</td>\n",
        "      <td>0</td>\n",
        "      <td>1</td>\n",
        "    </tr>\n",
        "    <tr>\n",
        "      <th>8</th>\n",
        "      <td>9</td>\n",
        "      <td>1</td>\n",
        "      <td>3</td>\n",
        "      <td>Johnson, Mrs. Oscar W (Elisabeth Vilhelmina Berg)</td>\n",
        "      <td>0</td>\n",
        "      <td>27.000000</td>\n",
        "      <td>0</td>\n",
        "      <td>2</td>\n",
        "      <td>347742</td>\n",
        "      <td>11.1333</td>\n",
        "      <td>NaN</td>\n",
        "      <td>S</td>\n",
        "      <td>0</td>\n",
        "      <td>1</td>\n",
        "    </tr>\n",
        "    <tr>\n",
        "      <th>9</th>\n",
        "      <td>10</td>\n",
        "      <td>1</td>\n",
        "      <td>2</td>\n",
        "      <td>Nasser, Mrs. Nicholas (Adele Achem)</td>\n",
        "      <td>0</td>\n",
        "      <td>14.000000</td>\n",
        "      <td>1</td>\n",
        "      <td>0</td>\n",
        "      <td>237736</td>\n",
        "      <td>30.0708</td>\n",
        "      <td>NaN</td>\n",
        "      <td>C</td>\n",
        "      <td>0</td>\n",
        "      <td>0</td>\n",
        "    </tr>\n",
        "  </tbody>\n",
        "</table>\n",
        "</div>"
       ],
       "metadata": {},
       "output_type": "pyout",
       "prompt_number": 22,
       "text": [
        "   PassengerId  Survived  Pclass  \\\n",
        "0            1         0       3   \n",
        "1            2         1       1   \n",
        "2            3         1       3   \n",
        "3            4         1       1   \n",
        "4            5         0       3   \n",
        "5            6         0       3   \n",
        "6            7         0       1   \n",
        "7            8         0       3   \n",
        "8            9         1       3   \n",
        "9           10         1       2   \n",
        "\n",
        "                                                Name  Sex        Age  SibSp  \\\n",
        "0                            Braund, Mr. Owen Harris    1  22.000000      1   \n",
        "1  Cumings, Mrs. John Bradley (Florence Briggs Th...    0  38.000000      1   \n",
        "2                             Heikkinen, Miss. Laina    0  26.000000      0   \n",
        "3       Futrelle, Mrs. Jacques Heath (Lily May Peel)    0  35.000000      1   \n",
        "4                           Allen, Mr. William Henry    1  35.000000      0   \n",
        "5                                   Moran, Mr. James    1  29.699118      0   \n",
        "6                            McCarthy, Mr. Timothy J    1  54.000000      0   \n",
        "7                     Palsson, Master. Gosta Leonard    1   2.000000      3   \n",
        "8  Johnson, Mrs. Oscar W (Elisabeth Vilhelmina Berg)    0  27.000000      0   \n",
        "9                Nasser, Mrs. Nicholas (Adele Achem)    0  14.000000      1   \n",
        "\n",
        "   Parch            Ticket     Fare Cabin Embarked  Embarked_Q  Embarked_S  \n",
        "0      0         A/5 21171   7.2500   NaN        S           0           1  \n",
        "1      0          PC 17599  71.2833   C85        C           0           0  \n",
        "2      0  STON/O2. 3101282   7.9250   NaN        S           0           1  \n",
        "3      0            113803  53.1000  C123        S           0           1  \n",
        "4      0            373450   8.0500   NaN        S           0           1  \n",
        "5      0            330877   8.4583   NaN        Q           1           0  \n",
        "6      0             17463  51.8625   E46        S           0           1  \n",
        "7      1            349909  21.0750   NaN        S           0           1  \n",
        "8      2            347742  11.1333   NaN        S           0           1  \n",
        "9      0            237736  30.0708   NaN        C           0           0  "
       ]
      }
     ],
     "prompt_number": 22
    },
    {
     "cell_type": "code",
     "collapsed": false,
     "input": [
      "# define X and y\n",
      "feature_cols = ['Pclass', 'Sex', 'Age', 'Embarked_Q', 'Embarked_S']\n",
      "X = titanic[feature_cols]\n",
      "y = titanic.Survived"
     ],
     "language": "python",
     "metadata": {},
     "outputs": [],
     "prompt_number": 23
    },
    {
     "cell_type": "code",
     "collapsed": false,
     "input": [
      "# fit a classification tree with max_depth=3 on all data\n",
      "from sklearn.tree import DecisionTreeClassifier\n",
      "treeclf = DecisionTreeClassifier(max_depth=3, random_state=1)\n",
      "treeclf.fit(X, y)"
     ],
     "language": "python",
     "metadata": {},
     "outputs": [
      {
       "metadata": {},
       "output_type": "pyout",
       "prompt_number": 24,
       "text": [
        "DecisionTreeClassifier(compute_importances=None, criterion='gini',\n",
        "            max_depth=3, max_features=None, max_leaf_nodes=None,\n",
        "            min_density=None, min_samples_leaf=1, min_samples_split=2,\n",
        "            random_state=1, splitter='best')"
       ]
      }
     ],
     "prompt_number": 24
    },
    {
     "cell_type": "code",
     "collapsed": false,
     "input": [
      "# create a GraphViz file\n",
      "export_graphviz(treeclf, out_file='tree_titanic.dot', feature_names=feature_cols)\n",
      "\n",
      "# At the command line, run this to convert to PNG:\n",
      "# dot -Tpng tree_titanic.dot -o tree_titanic.png"
     ],
     "language": "python",
     "metadata": {},
     "outputs": [],
     "prompt_number": 25
    },
    {
     "cell_type": "markdown",
     "metadata": {},
     "source": [
      "![Tree for Titanic data](images/tree_titanic.png)"
     ]
    },
    {
     "cell_type": "markdown",
     "metadata": {},
     "source": [
      "Notice the split in the bottom right: the **same class** is predicted in both of its leaves. That split didn't affect the **classification error rate**, though it did increase the **node purity**, which is important because it increases the accuracy of our predicted probabilities."
     ]
    },
    {
     "cell_type": "code",
     "collapsed": false,
     "input": [
      "# compute the feature importances\n",
      "pd.DataFrame({'feature':feature_cols, 'importance':treeclf.feature_importances_})"
     ],
     "language": "python",
     "metadata": {},
     "outputs": [
      {
       "html": [
        "<div style=\"max-width:1500px;overflow:auto;\">\n",
        "<table border=\"1\" class=\"dataframe\">\n",
        "  <thead>\n",
        "    <tr style=\"text-align: right;\">\n",
        "      <th></th>\n",
        "      <th>feature</th>\n",
        "      <th>importance</th>\n",
        "    </tr>\n",
        "  </thead>\n",
        "  <tbody>\n",
        "    <tr>\n",
        "      <th>0</th>\n",
        "      <td>Pclass</td>\n",
        "      <td>0.242664</td>\n",
        "    </tr>\n",
        "    <tr>\n",
        "      <th>1</th>\n",
        "      <td>Sex</td>\n",
        "      <td>0.655584</td>\n",
        "    </tr>\n",
        "    <tr>\n",
        "      <th>2</th>\n",
        "      <td>Age</td>\n",
        "      <td>0.064494</td>\n",
        "    </tr>\n",
        "    <tr>\n",
        "      <th>3</th>\n",
        "      <td>Embarked_Q</td>\n",
        "      <td>0.000000</td>\n",
        "    </tr>\n",
        "    <tr>\n",
        "      <th>4</th>\n",
        "      <td>Embarked_S</td>\n",
        "      <td>0.037258</td>\n",
        "    </tr>\n",
        "  </tbody>\n",
        "</table>\n",
        "</div>"
       ],
       "metadata": {},
       "output_type": "pyout",
       "prompt_number": 26,
       "text": [
        "      feature  importance\n",
        "0      Pclass    0.242664\n",
        "1         Sex    0.655584\n",
        "2         Age    0.064494\n",
        "3  Embarked_Q    0.000000\n",
        "4  Embarked_S    0.037258"
       ]
      }
     ],
     "prompt_number": 26
    },
    {
     "cell_type": "markdown",
     "metadata": {},
     "source": [
      "# Part 3: Comparing decision trees with other models\n",
      "\n",
      "**Advantages of decision trees:**\n",
      "\n",
      "- Can be used for regression or classification\n",
      "- Can be displayed graphically\n",
      "- Highly interpretable\n",
      "- Can be specified as a series of rules, and more closely approximate human decision-making than other models\n",
      "- Prediction is fast\n",
      "- Features don't need scaling\n",
      "- Automatically learns feature interactions\n",
      "- Tends to ignore irrelevant features\n",
      "- Non-parametric (will outperform linear models if relationship between features and response is highly non-linear)"
     ]
    },
    {
     "cell_type": "markdown",
     "metadata": {},
     "source": [
      "![Trees versus linear models](images/tree_vs_linear.png)"
     ]
    },
    {
     "cell_type": "markdown",
     "metadata": {},
     "source": [
      "**Disadvantages of decision trees:**\n",
      "\n",
      "- Performance is (generally) not competitive with the best supervised learning methods\n",
      "- Can easily overfit the training data (tuning is required)\n",
      "- Small variations in the data can result in a completely different tree (high variance)\n",
      "- Recursive binary splitting makes \"locally optimal\" decisions that may not result in a globally optimal tree\n",
      "- Doesn't tend to work well if the classes are highly unbalanced\n",
      "- Doesn't tend to work well with very small datasets"
     ]
    }
   ],
   "metadata": {}
  }
 ]
}